package org.gilgamesh.stool.search.es;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import org.elasticsearch.search.sort.SortOrder;
import org.gilgamesh.stool.search.es.param.BoolParam;
import org.gilgamesh.stool.search.es.param.RangeTimeParam;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * Elastic Search查询条件
 *
 * @author Gilgamesh
 * @since 2021-08-20
 **/
public class ESSearchRequest extends AbstractESRequest implements Serializable {
    private static final long serialVersionUID = -7807463649613466505L;

    /**
     * 时间范围
     **/
    private RangeTimeParam rangeTimeParam;

    /**
     * 排序方式
     **/
    private SortOrder sort;

    /**
     * 需要排序的字段
     **/
    private String sortField;

    /**
     * 查询的must条件
     **/
    private List<BoolParam> must;

    /**
     * 查询的should条件
     **/
    private List<BoolParam> should;

    /**
    * 你希望什么字段成为结果集的主键
    **/
    private String primaryKeyField;

    /**
     * 获取rangeTime
     **/
    public RangeTimeParam rangeTime() {
        if (rangeTimeParam == null) {
            rangeTimeParam = new RangeTimeParam(this);
        }
        return rangeTimeParam;
    }

    /**
     * 设置rangeTime
     **/
    public ESSearchRequest setRangeTime(RangeTimeParam rangeTime) {
        this.rangeTimeParam = rangeTime;
        return this;
    }

    /**
     * 是否需要按照时间范围
     **/
    @Override
    public boolean isRangeTime() {
        return rangeTimeParam != null;
    }

    /**
     * 是否需要排序
     **/
    @Override
    public boolean isSorted() {
        return sort != null && StrUtil.isNotEmpty(sortField);
    }

    /**
     * 有must条件
     **/
    public boolean hasMust() {
        return CollectionUtil.isNotEmpty(must);
    }

    /**
     * 有should条件
     **/
    public boolean hasShould() {
        return CollectionUtil.isNotEmpty(should);
    }

    /**
     * 获取排序类型
     **/
    public SortOrder sort() {
        return this.sort;
    }

    /**
     * 获取排序字段
     **/
    public String sortField() {
        return this.sortField;
    }

    /**
     * 设置排序方式
     **/
    public ESSearchRequest sort(SortOrder sort) {
        this.sort = sort;
        return this;
    }

    /**
     * 设置排序字段
     **/
    public ESSearchRequest sortField(String sortField) {
        this.sortField = sortField;
        return this;
    }

    /**
     * 设置排序方式
     **/
    public ESSearchRequest sort(String sortField, SortOrder sort) {
        this.sortField = sortField;
        this.sort = sort;
        return this;
    }

    /**
     * 设置必要条件
     **/
    public ESSearchRequest must(BoolParam must) {
        if (CollUtil.isEmpty(this.must)) {
            this.must = new ArrayList<>();
        }
        /* filed和values都有值才添加 */
        if(StrUtil.isNotEmpty(must.getField()) && CollUtil.isNotEmpty(must.getValues())) {
            this.must.add(must);
        }
        return this;
    }

    /**
     * 设置should条件
     **/
    public ESSearchRequest should(BoolParam should) {
        if (CollUtil.isEmpty(this.should)) {
            this.should = new ArrayList<>();
        }
        this.should.add(should);
        return this;
    }

    /**
     * 获取must条件
     **/
    public List<BoolParam> must() {
        return this.must;
    }

    /**
     * 获取should条件
     **/
    public List<BoolParam> should() {
        return should;
    }

    /**
    * 返回结果的key
    **/
    public String primaryKeyField(){
        return this.primaryKeyField;
    }

    public ESSearchRequest primaryKeyField(String primaryKeyField){
        this.primaryKeyField = primaryKeyField;
        return this;
    }

    public String choosePrimaryKeyField(){
        if(StrUtil.isNotBlank(this.primaryKeyField)){
            return this.primaryKeyField;
        }
        if(hasNeedField()){
            return this.needFields()[0];
        }
        if(CollUtil.isNotEmpty(must)){
            return this.must.get(0).getField();
        }
        if(CollUtil.isNotEmpty(should)){
            return this.should.get(0).getField();
        }
        if(StrUtil.isNotBlank(sortField)){
            return this.sortField;
        }
        return "DEFAULT_KEY";
    }
}
